package dto

import (
	"encoding/json"
	"errors"
	"fmt"
	"net/url"
	"yunj/pkg/global"
	"yunj/pkg/yunj/app/enum/stateenum"
	"yunj/pkg/yunj/app/model"
	"yunj/pkg/yunj/util"

	"github.com/worklz/go-validate"
	"gorm.io/gorm"
)

type AdminMemberPageListFilterFormParam struct {
	Keywords      string   `json:"keywords"`
	DepartmentIds []uint64 `json:"department_ids"`
	PostionIds    []uint64 `json:"postion_ids"`
	RoleIds       []uint64 `json:"role_ids"`
}

type AdminMemberPageListItemResponse struct {
	Id                   uint64   `json:"id"`
	Name                 string   `json:"name"`
	Username             string   `json:"username"`
	LastLoginIp          string   `json:"last_login_ip"`
	LastLoginAt          string   `json:"last_login_at"`
	CreatedAt            string   `json:"created_at"`
	UpdatedAt            string   `json:"updated_at"`
	DepartmentIds        []uint64 `json:"department_ids"`
	DepartmentPostionIds []uint64 `json:"department_postion_ids"`
	RoleIds              []uint64 `json:"role_ids"`
}

type AdminMemberPageFormLoadResponse struct {
	Id                   uint64   `json:"id"`
	Username             string   `json:"username"`
	Name                 string   `json:"name"`
	DepartmentIds        []uint64 `json:"department_ids"`
	DepartmentPostionIds []uint64 `json:"department_postion_ids"`
	RoleIds              []uint64 `json:"role_ids"`
}

type AdminMemberPageDepartmentPostionDropdownSearchItem struct {
	Id             uint64 `json:"id"`
	Type           uint8  `json:"type"`
	DepartmentType uint8  `json:"department_type"`
	DepartmentName string `json:"department_name"`
	PostionName    string `json:"postion_name"`
}

// 登录数据
type AdminMemberLoginData struct {
	validate.Validator
	ParamData   string `json:"data"`
	Username    string `json:"username"`
	Password    string `json:"password"`
	CaptchaCode string `json:"captchaCode"`
	CaptchaHash string `json:"captchaHash"`

	AdminMember *model.AdminMember // 登录后台成员模型对象
}

func (v *AdminMemberLoginData) DefineRules() map[string]interface{} {
	return map[string]interface{}{
		"data": "required|IsParamData",
	}
}

func (v *AdminMemberLoginData) DefineMessages() map[string]string {
	return map[string]string{
		"data.required": "参数异常！",
	}
}

// 校验data有效性
func (v *AdminMemberLoginData) IsParamData(value interface{}, param string, datas map[string]interface{}, title string) (err error) {
	dataUrlDecode, err := url.QueryUnescape(v.ParamData)
	if err != nil {
		err = fmt.Errorf("参数[data]错误1！%v", err)
		return
	}
	dataMap, err := util.JsonTo[map[string]string](dataUrlDecode)
	if err != nil {
		err = fmt.Errorf("参数[data]错误2！%v", err)
		return
	}
	aesEncrypted, exists1 := dataMap["data"]
	aesKey, exists2 := dataMap["key"]
	aesIv, exists3 := dataMap["iv"]
	if !exists1 || !exists2 || !exists3 {
		err = fmt.Errorf("参数[data]错误3！")
		return
	}
	decryptStr, err := util.AesDecrypt(aesEncrypted, aesKey, aesIv)
	if err != nil {
		err = fmt.Errorf("参数[data]错误5！%v", err)
		return
	}
	err = json.Unmarshal([]byte(decryptStr), v)
	if err != nil {
		err = fmt.Errorf("参数[data]错误6！%v", err)
		return
	}
	return
}

// 进一步处理数据
func (v *AdminMemberLoginData) HandleDatas(datas map[string]interface{}, scene string) (err error) {
	if v.Username == "" {
		err = errors.New("请输入用户名")
		return
	}
	if v.Password == "" {
		err = errors.New("请输入密码")
		return
	}
	if v.CaptchaHash == "" {
		err = errors.New("验证码异常！请重新获取")
		return
	}
	if v.CaptchaCode == "" {
		err = errors.New("请输入验证码")
		return
	}
	res, err := global.Captcha.Check(v.CaptchaHash, v.CaptchaCode)
	if err != nil {
		err = fmt.Errorf("验证码校验异常！%v", err)
		return
	}
	if !res {
		err = errors.New("验证码错误")
		return
	}

	var adminMember model.AdminMember
	err = global.MySQL.Preload("Roles").Where("username = ? and state <> ?", v.Username, stateenum.DELETED).First(&adminMember).Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			err = errors.New("账户不存在")
		} else {
			err = fmt.Errorf("账户匹配异常！%v", err)
		}
		return
	}
	if adminMember.State != stateenum.NORMAL {
		err = errors.New("账户已冻结")
		return
	}
	if len(adminMember.GetOwnRoles()) <= 0 {
		err = errors.New("当前账户未分配有效角色")
		return
	}
	passwordHash := util.PasswordGenerate(v.Password, adminMember.PasswordSalt)
	if passwordHash != adminMember.PasswordHash {
		err = errors.New("账户或密码错误")
		return
	}
	v.AdminMember = &adminMember
	return
}
